﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using System.Collections;

namespace CCPnuts.Pack
{
    public static class Util
    {
        public static object NNTar(IPacker packer)
        {
            if (packer != null)
            {
                Debug.Assert(packer._Packed != null);
                return packer._Packed;
            }
            else
            {
                return null;
            }
        }

        public static object NNTar(IPacked packed)
        {
            if (packed != null)
            {
                PackedInfo pi = packed._PackedInfo;
                Debug.Assert(pi != null);
                if (pi.Packer == null)
                {
                    pi.Packer = pi.Cons(packed);
                }
                return pi.Packer;
            }
            else
            {
                return null;
            }
        }
    }

    public class EnumeratorPacker<T, S> : IEnumerator<T>
        where T : IPacker
        where S : IPacked
    {

        private IEnumerator<S> Packed { get; set; }

        public EnumeratorPacker(IEnumerator<S> packed)
        {
            Debug.Assert(packed != null);
            Packed = packed;
        }

        #region IEnumerator<T> Members

        public T Current
        {
            get { return (T)((IEnumerator)this).Current; }
        }

        #endregion

        #region IDisposable Members

        public void Dispose()
        {
            try
            {
                Packed.Dispose();
            }
            catch (Exception ex)
            {
                throw ex.Pack("Exception @ EnumeratorPacker<T, S> Dispose()");
            }
        }

        #endregion

        #region IEnumerator Members

        object System.Collections.IEnumerator.Current
        {
            get
            {
                //try
                //{
                    return Util.NNTar(Packed.Current);
                //}
                //catch (Exception ex)
                //{
                    //throw ex.Pack("Exception @ EnumeratorPacker<T, S> : Current : Get");
                //}
            }
        }

        public bool MoveNext()
        {
            try
            {
                return Packed.MoveNext();
            }
            catch (Exception ex)
            {
                throw ex.Pack("Exception @ EnumeratorPacker<T, S> MoveNext()");
            }
        }

        public void Reset()
        {
            try
            {
                Packed.Reset();
            }
            catch (Exception ex)
            {
                throw ex.Pack("Exception @ EnumeratorPacker<T, S> Reset()");
            }
        }

        #endregion
    }
}
